<?php
/* 
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of BasketSessionBased
 *
 * @author aneto
 */
class BasketSessionBased extends myBasket{

	/** add product to session basket */
	public function addProduct($productID, $qty = 1){
		if( !Doctrine::getTable('Product')->find($productID) ) return false;

		if($qty <= 0)$qty = 1;

		$products = array();
		if($this->getUser()->hasAttribute('basket.products')){
			$products = $this->getUser()->getAttribute('basket.products');
		}

		$qty = isset($products[$productID]) && is_integer((int)$products[$productID]) ? $products[$productID] + $qty : $qty;
		$this->changeAmount($productID, $qty);

		return true;
	}

	public function setShippingAddress($data){
		$this->getUser()->setAttribute('basket.shipping.address', $data);
	}

	public function setBillingAddress($data){
		$this->getUser()->setAttribute('basket.billing.address', $data);
	}

	public function getShippingAddress(){
		return $this->getAddress('shipping');
	}

	public function getBillingAddress(){
		return $this->getAddress('billing');
	}

	protected function getAddress($type){
		$address = $this->getUser()->getAttribute("basket.$type.address", array());

		// if user is authenticated then return first address of apropriate type
		if(empty($address) && $this->getUser()->isAuthenticated()){
			$address = Doctrine::getTable('PublicUserAddresses')->findOneByTypeAndPublicUserId(
					$type,
					$this->getUser()->getObject()->getId()
			);

			if($address){
				return $address->toArray();
			}else{
				return array();
			}
		}
		return $address;
	}

	public function renderShippingAddress(){
		return $this->renderAddress($this->getShippingAddress());
	}

	public function renderBillingAddress(){
		return $this->renderAddress($this->getShippingAddress());
	}

	protected function renderAddress($address){
		return sprintf('%s, %s, %s, %s, %s', $address['address'],$address['city'],$address['state'],$address['zip'],$address['country']);
	}


	public function setShippingZone($zoneID){
		$this->getUser()->setAttribute('basket.products.shipping.zone', $zoneID);
	}


	public function price($type = myBasket::TOTAL_PAYABLE){
		$result = 0;

		switch($type){
			case myBasket::TOTAL_PAYABLE:
				$result = $this->getTotalPayable();
				break;
			case myBasket::TOTAL_NO_SHIPPING:
				$result = $this->getTotalPrice();
				break;
			case myBasket::SHIPPING_PRICE:
				$result = $this->getShippingPrice();
				break;
			default:
				throw new Exception('wrong price type');
		}

		return $result;
	}

	public function getShippingZone(){
		return $this->getUser()->getAttribute('basket.products.shipping.zone');
	}

	public function renderShippingZone(){
		$zone = Doctrine::getTable('ShippingZone')->find($this->getShippingZone());

		return $zone['name'];
	}

	public function getProducts(){
		return $this->getUser()->getAttribute('basket.products', array());
	}

	public function getProductAmount($productID){
		$products = $this->getProducts();
		return isset($products[$productID]) && is_integer((int)$products[$productID]) ? $products[$productID] : 0;
	}

	public function prepareDataForView(){
		$result = array();

		$basketInfo = $this->getProducts();
		$ids = array(-1);
		foreach($basketInfo as $id => $val){
			$ids[] = $id;
		}
		
		$q = Doctrine::getTable('Product')->createQuery('basketProds')
						->from('Product p')
						->innerJoin('p.Translation t')
						->leftJoin('p.ProductPictures pp')
						->orderBy('p.pri asc')
						->addOrderBy('pp.pri asc')
						->whereIn('p.id', $ids);

		foreach($q->execute() as $item){
			$result[] = new myBasketItem($item,$basketInfo[$item->getId()]);
		}

		return $result;
	}


	public function shippingCost($zoneID = false){
		if(!$zoneID){
			$zoneID = $this->getShippingZone();
		}
		$interval = $this->shippingZoneInterval($zoneID);
		return $interval['price'];
	}
	
	public function shippingZoneInterval($zoneID = false){
		if(!$zoneID){
			$zoneID = $this->getShippingZone();
		}
		if($zoneID){
			$mass = $this->getOrderMass();
			foreach(Doctrine::getTable('ShippingZone')->find($zoneID)->Intervals as $interval){
				if($interval['start'] <= $mass && $interval['end'] >= $mass) return $interval;
			}
		}
		return array('start' => 0, 'end' => 1000000000, 'price' => 0);	
	}

	private function getOrderMass(){
		return 200;
	}

	private function getShippingPrice(){
		return $this->shippingCost();
	}

	public function getTotalPayable(){
		return $this->getShippingPrice() + $this->getTotalPrice();
	}


	public function countItems(){
		$result = 0;

		foreach($this->getProducts() as $id => $q){
			$result += $q;
		}

		return $result;
	}

	public function deleteProduct($id){
		$ar = $this->getProducts();
		unset($ar[$id]);

		$this->setProducts($ar);
		return true;
	}

	public function changeAmount($productID, $qty = 1){
		$products = array();

		$prod = Doctrine::getTable('Product')->find($productID);
		if($prod['instock'] < $qty)$qty = $prod['instock'];
		
		if($this->getUser()->hasAttribute('basket.products')){
			$products = $this->getUser()->getAttribute('basket.products');
		}

		$products[$productID] = $qty;
		$this->getUser()->setAttribute('basket.products', $products);

	}

	public function isEmpty(){
		return  $this->getProducts() ? false : true;
	}

	public function getTotalPrice(){
		$result = 0;
		foreach($this->prepareDataForView() as $prod)
			$result += $prod->getPrice();
		return $result;
	}

	private function setProducts( array $products ){
		$this->getUser()->setAttribute('basket.products', $products);
	}




	private function getUser(){
		 return sfContext::getInstance()->getUser();
	}


	public function checkout(){

		$rawShippingdata = $this->getShippingAddress();
		$interval = $this->shippingZoneInterval();
		$shippingData = array(
				'information' => $this->renderShippingAddress() ,
				'name' => $rawShippingdata['name'],
				'cost' => $this->price(myBasket::SHIPPING_PRICE),
				'mass_interval_start' => $interval['start'],
				'mass_interval_end' => $interval['end'],
				'vatrate' => 20
		);


		$rawBillingData = $this->getBillingAddress();
		$billingData = array(
			'country' => $rawBillingData['country'],
			'city' => $rawBillingData['city'],
			'street' => $rawBillingData['address'],
			'zip' => $rawBillingData['zip'],
			'receiver' => $rawBillingData['name'],
			'email' => $rawBillingData['email']

		);
                $pUser = $this->getUser()->getObject();
                if (!$pUser) {
                  $pUser = Doctrine::getTable('PublicUser')->find(5);
                }
		$order =  Doctrine::getTable('ProductOrder')->checkout(
				$this->getProducts(),
				$pUser,
				$this->getUser()->getCurrency(),
				$billingData,
				$shippingData
		);

		return $order;
	}
}
?>
